#include "SiemensMC45.h"
#include "nmea_0183.h"
#include "GPS_GSM_Tracker.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "softSerialReceiver.h"
#include "softSerialTransmitter.h"
#include "usart0.h"
#include "system.h"
#include "dataIO.h"
#include <string.h>

/*
 * The GPS does not have nonvolatile storage of set baud rate, and defaults
 * to 38400, too fast for software UART. It gets the hardware UART.
 * The GSM module is set to 4800 baud and gets the software UAT and T.
 */
USART0 gpsUSART(38400);
SoftSerialReceiver gsmUSARTRx(4800);
SoftSerialTransmitter gsmUSARTTx(4800);
DataOutput* debugUSART;

NMEA_GPS gps(&gpsUSART);
SiemensMC45 gsm(&gsmUSARTRx, &gsmUSARTTx);

volatile uint32_t systemTimeMillis;

void sleep(int millis) {
	/*
	// Wait for Timer1...
	cli();
	uint32_t timeout = systemTimeMillis + millis;
	sei();
	uint32_t check;
	do {
		cli();
		check = systemTimeMillis;
		sei();
	}
	while (check<timeout);
	*/

	uint32_t timeout = systemTimeMillis + millis;
	while(systemTimeMillis<timeout);
}

uint32_t getSystemTimeMillis() {
	/*
	cli();
	uint32_t result = systemTimeMillis;
	sei();
	return result;
	*/
	return systemTimeMillis;
}

#define ACTIVITY_LED_PORT PORTB
#define ACTIVITY_LED_DDR DDRB
#define ACTIVITY_LED_BIT 5

void updateStatusIndicators() {
	static uint8_t activityCounter = 0;
	// if (activityCounter++ & 1) {
	// if (receivedBytes & 1) {
	// if (receivedGPSPackets & 1) {
	/*
	if (sendNumSMSListRequests & 1) {
		ACTIVITY_LED_PORT |= (1<<ACTIVITY_LED_BIT);
	} else {
		ACTIVITY_LED_PORT &= ~(1<<ACTIVITY_LED_BIT);
	}
	*/
}

void setLED(bool led) {
	if (led)
		ACTIVITY_LED_PORT |= 1<<ACTIVITY_LED_BIT;
	else
		ACTIVITY_LED_PORT &= ~(1<<ACTIVITY_LED_BIT);
}

void toggleLED() {
	ACTIVITY_LED_PORT ^= 1<<ACTIVITY_LED_BIT;
}

void debugString(char* string) {
	/*
	int index = 0;
	int length = strlen(string);
	while(index<length) {
		if (debugUSART->tryWrite(string[index]))
			index++;
	}
	*/
}

void initIO() {
	ACTIVITY_LED_DDR |= (1<<ACTIVITY_LED_BIT);

	// And timer1 also: Deliver 1kHz interrupts of some kind.
	// That would be: Prescale by 8 and CTC with value of 1000.
	TCNT1 = 0;
	OCR1A = 1000;
	TCCR1A = 0;
	TCCR1B = (1<<WGM12)|(1<<CS11);
	TIMSK1 = (1<<OCIE1A);
}

ISR(TIMER1_COMPA_vect) {
	systemTimeMillis++;
}

extern "C" {
  void __cxa_pure_virtual()
  {
    // put error handling here
	// PORTB |= 1<<5;
  }
}

/*
void* operator new (size_t size) {
	return malloc(size);
}
*/

int main() {
	initIO();
	// debugUSART = new SoftSerialTransmitter(4800);
	sei();
	mainLoop();
	return 1;
}
